package wiziqi;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;

public class GameFace extends JFrame implements Runnable {
    String game_title = "欢乐五子棋";
    String black_time = "黑棋下棋时间:";
    String white_time = "白棋下棋时间:";
    boolean whotime = false;
    boolean game_start = false; // 游戏开始标志
    int click_x;// 鼠标点击的x坐标
    int click_y;// 鼠标点击的y坐标
    boolean isblack = true;// true：黑子 false:白子
    int[][] qizi = new int[19][19];// 保存棋子  0:无子 1:黑子 2：白子
    int index_x;// 棋子相对于棋盘的x坐标
    int index_y;// 棋子相对于棋盘的y坐标
    int[] x = new int[255];//用来储存棋子的位置，以便悔棋
    int[] y = new int[255];//写255是因为，写大点，每次悔棋没清掉
    int cout_x = 0;//x的下标 ^
    int cout_y = 0;//y的下标 | 用来自增
    boolean ishave = false;//判断棋盘是否有棋子
    int time = 0;//输入的时间 单位（秒/s）
    int blacktime = 0;//设置黑方游戏时间（s）
    int whitetime = 0;//设置白方游戏时间（s）
    String blackmessage = "无限制";//保存黑棋的显示信息
    String whitemessage = "无限制";//保存白棋的显示信息
    Thread t = new Thread(this);//创建线程

    // 游戏初始化设置
    public void init() {
        t.start();//启动线程
        t.suspend();//挂起线程
        Container container = this.getContentPane();
        this.setTitle("五子棋");
        // 窗体背景设置
//        ImageIcon image = new ImageIcon("D:\\javaWeb\\MyGame\\src\\images\\board.jpg");
        ImageIcon image = new ImageIcon("src\\images\\board.jpg");
        JLabel label = new JLabel(image);
        label.setSize(500, 500);
        container.add(label);

        // 添加鼠标事件监听
        this.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                click_x = e.getX();
                click_y = e.getY();

                // 点击开始游戏操作
                if (click_x >= 400 && click_x <= 470 && click_y >= 75 && click_y <= 105) {
                    //开始黑棋先下
                    game_title = "黑方落子";
                    repaint();
                    isblack = true;
                    blacktime = time;
                    whitetime = time;
                    JOptionPane.showMessageDialog(null, "游戏开始！");
                    game_start = true;
                    //清空棋盘
                    for (int i = 0; i < 19; i++) {
                        for (int j = 0; j < 19; j++) {
                            qizi[i][j] = 0;
                        }
                    }
                    repaint();

                }

                // 点击游戏设置操作
                if (click_x >= 400 && click_x <= 470 && click_y >= 129 && click_y <= 159) {
                    //input必须为数字 time必须>=0
                    String input = JOptionPane.showInputDialog("请输入下棋时间,单位：（秒/s），若输入为0则无时间限制");
                    try {
                        time = Integer.parseInt(input);
                        if (time < 0) {
                            JOptionPane.showMessageDialog(null, "请正确输入信息！不允许输入负数！");
                        } else if (time > 0) {
                            int res2 = JOptionPane.showConfirmDialog(null, "设置成功，是否重新开始游戏");
                            if (res2 == 0) {
                                // t.suspend();
                                t.resume();//启动线程
                                isblack = true;
                                game_title = "黑方落子";
                                game_start = true;
                                blacktime = time;
                                whitetime = time;
                                blackmessage = blacktime + "";
                                whitemessage = whitetime + "";
                                //重新开始 清空棋盘
                                repaint();
                                for (int i = 0; i < 19; i++) {
                                    for (int j = 0; j < 19; j++) {
                                        qizi[i][j] = 0;
                                    }
                                }
                                repaint();
                            }
                        } else if (time == 0) {
                            int res2 = JOptionPane.showConfirmDialog(null, "设置成功，是否重新开始游戏");
                            if (res2 == 0) {
                                //重新开始 清空棋盘
                                t.suspend();
                                isblack = true;
                                game_title = "黑方落子";
                                game_start = true;
                                blacktime = time;
                                whitetime = time;
                                blackmessage = "无限制";
                                whitemessage = "无限制";
                                repaint();
                                for (int i = 0; i < 19; i++) {
                                    for (int j = 0; j < 19; j++) {
                                        qizi[i][j] = 0;
                                    }
                                }
                                repaint();
                            }
                        }
                    } catch (NumberFormatException numberFormatException) {
                        JOptionPane.showMessageDialog(null, "请正确输入信息！！");
                    }

                }

                // 点击游戏说明
                if (click_x >= 400 && click_x <= 470 && click_y >= 173 && click_y <= 204) {
                    JOptionPane.showMessageDialog(null, "先将五个相同的棋子连成线的人赢！");

                }

                // 点击悔棋操作
                if (click_x >= 400 && click_x <= 470 && click_y >= 228 && click_y <= 259 && game_start) {
                    //判断棋盘上是否有棋子 悔棋之后还要将flag变掉
                    ishave = false;//不加这个当悔棋完了，再点悔棋会异常，加这个每次默认无棋子，反正后面还要重新判断
                    for (int i = 0; i < 19; i++) {
                        for (int j = 0; j < 19; j++) {
                            if (qizi[i][j] != 0) {
                                ishave = true;
                            }
                        }
                    }
                    if (ishave) {
                        if (isblack) {
                            //把棋子去掉
                            qizi[x[--cout_x]][y[--cout_y]] = 0;
                            repaint();
                            isblack = false;
                            game_title = "白方落子";
                            blacktime = time;
                            whitetime = time;
                            repaint();
                        } else {
                            qizi[x[--cout_x]][y[--cout_y]] = 0;
                            repaint();
                            isblack = true;
                            game_title = "黑方落子";
                            blacktime = time;
                            whitetime = time;
                            repaint();
                        }
                    } else {
                        JOptionPane.showMessageDialog(null, "棋盘上没有棋子！");
                    }
                }

                // 点击认输操作
                if (click_x >= 400 && click_x <= 470 && click_y >= 277 && click_y <= 309 && game_start) {
                    //白方认输
                    if (game_title.equals("白方落子")) {
                        t.suspend();
                        int res = JOptionPane.showConfirmDialog(null, "现在是白方，确定认输吗？");
                        if (res == 0) {
                            int res1 = JOptionPane.showConfirmDialog(null, "恭喜黑方获胜，继续吗？");
                            if (res1 == 0) {
                                for (int i = 0; i < 19; i++) {
                                    for (int j = 0; j < 19; j++) {
                                        qizi[i][j] = 0;
                                    }
                                }
                                repaint();
                                blacktime = time;
                                whitetime = time;
                                t.resume();
                            } else {
                                game_start = false;
                                t.suspend();
                            }
                        } else {
                            JOptionPane.showMessageDialog(null, "游戏继续！");
                        }
                    }
                    //黑方认输
                    if (game_title.equals("黑方落子")) {
                        t.suspend();
                        int res = JOptionPane.showConfirmDialog(null, "现在是黑方，确定认输吗？");
                        if (res == 0) {
                            int res1 = JOptionPane.showConfirmDialog(null, "恭喜白方获胜，继续吗？");
                            if (res1 == 0) {
                                for (int i = 0; i < 19; i++) {
                                    for (int j = 0; j < 19; j++) {
                                        qizi[i][j] = 0;
                                    }
                                }
                                repaint();
                                blacktime = time;
                                whitetime = time;
                                t.resume();
                            } else {
                                game_start = false;
                                t.suspend();
                            }
                        } else {
                            JOptionPane.showMessageDialog(null, "游戏继续！");
                        }
                    }
                }

                // 点击关于操作
                if (click_x >= 400 && click_x <= 470 && click_y >= 326 && click_y <= 356) {
                    JOptionPane.showMessageDialog(null, "关于");
                }

                // 点击退出操作
                if (click_x >= 400 && click_x <= 470 && click_y >= 377 && click_y <= 406) {
                    JOptionPane.showMessageDialog(null, "退出成功！");
                    System.exit(0);
                }

                // 点击棋盘落子操作 下棋
                if (click_x >= 10 && click_x <= 370 && click_y >= 75 && click_y <= 435 && game_start) {
                    // 30,95 => 1,1
                    index_x = Math.round((click_x - 10) / 20f);
                    index_y = Math.round((click_y - 75) / 20f);

                    if (qizi[index_x][index_y] == 0) //判断是否有棋子
                    {
                        x[cout_x++] = index_x;
                        y[cout_y++] = index_y;
                        if (isblack) {
                            qizi[index_x][index_y] = 1;// 保存黑子
                            isblack = false;
                            game_title = "白方落子";
                            blacktime = time;
                        } else {
                            qizi[index_x][index_y] = 2;// 保存白子
                            isblack = true;
                            game_title = "黑方落子";
                            whitetime = time;
                        }
                    } else if (qizi[index_x][index_y] == 1) {
                        JOptionPane.showMessageDialog(null, "该位置有黑棋了，请下另个地方！");
                    } else {
                        JOptionPane.showMessageDialog(null, "该位置有白棋了，请下另个地方！");
                    }
                    repaint();
                    boolean winFlag = isWin();


                    //赢了之后的操作
                    if (winFlag) {
                        t.suspend();
                        if (qizi[index_x][index_y] == 1) {
                            int res = JOptionPane.showConfirmDialog(null, "黑方赢了,继续吗?");
                            //按确认就会清空
                            if (res == 0) {
                                t.resume();//唤醒线程
                                for (int i = 0; i < 19; i++) {
                                    for (int j = 0; j < 19; j++) {
                                        qizi[i][j] = 0;
                                    }
                                }
                                blacktime = time;
                                whitetime = time;
                                isblack = true;
                                game_title = "黑方落子";
                                repaint();

                            } else {
                                game_start = false;
                                t.suspend();
                            }
                        }
                        if (qizi[index_x][index_y] == 2) {
                            int res = JOptionPane.showConfirmDialog(null, "白方赢了,继续吗?");
                            //按确认就会清空
                            if (res == 0) {
                                for (int i = 0; i < 19; i++) {
                                    for (int j = 0; j < 19; j++) {
                                        qizi[i][j] = 0;
                                    }
                                }
                                repaint();
                                blacktime = time;
                                whitetime = time;
                                t.resume();
                            } else {
                                game_start = false;
                                t.suspend();
                            }
                        }
                    }
                }
            }
        });

        this.setSize(500, 500);// 设置宽高
        this.setLocationRelativeTo(null);// 居中
        this.setVisible(true);
        this.setResizable(false);// 设置大小不可变
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    /*
     *       棋盘绘制
     */
    @Override
    public void paint(Graphics g) {
        super.paint(g);
        //双缓冲技术 防止屏幕闪烁
        BufferedImage bi = new BufferedImage(500, 500, BufferedImage.TYPE_INT_ARGB);
        Graphics g2 = bi.createGraphics();

        // 绘制五子棋标题
        Font font = new Font("楷体", Font.BOLD, 30);
        g2.setFont(font);
        g2.setColor(Color.white);
        g2.drawString(game_title, 130, 62);

        //黑棋时间限制
        Font font1 = new Font("微软雅黑", Font.BOLD, 20);
        g2.setFont(font1);
        g2.setColor(Color.black);
        g2.drawString(black_time + blackmessage, 24, 480);

        //白棋时间限制
        Font font2 = new Font("微软雅黑", Font.BOLD, 20);
        g2.setFont(font2);
        g2.setColor(Color.black);
        g2.drawString(white_time + whitemessage, 245, 480);

        // 棋盘格绘制
        for (int i = 1; i < 18; i++) {
            // 画横线
            g2.drawLine(10, 75 + 20 * i, 370, 75 + 20 * i);
            // 画竖线
            g2.drawLine(10 + 20 * i, 75, 10 + 20 * i, 435);
        }

        // 绘制棋子
        for (int i = 0; i < 19; i++) {
            for (int j = 0; j < 19; j++) {
                //将点击的储存起来，然后用循环找
                if (qizi[i][j] == 1) {
                    g2.setColor(Color.BLACK);
                    //30 95
                    g2.fillOval(i * 20 + 10 - 8, j * 20 + 75 - 8, 16, 16);
                }
                if (qizi[i][j] == 2) {
                    g2.setColor(Color.white);
                    g2.fillOval(i * 20 + 10 - 8, j * 20 + 75 - 8, 16, 16);
                }
            }
        }
        g.drawImage(bi, 0, 0, this);
    }

    /*
     *  判断输赢
     *  某一个方向上相同颜色的棋子个数是否达到5个
     */

    public boolean isWin() {
        boolean flag = false;//输赢
        int count = 1;//相连个数
        int color = qizi[index_x][index_y];//记录棋子颜色
        //判断横向棋子是否相连
        //向右
        int i = 1;//迭代数
        while ((index_x + i) >= 0 && (index_x + i) <= 18
                && (index_y) >= 0 && (index_y) <= 18
                && color == qizi[index_x + i][index_y]) {
            count++;
            i++;
        }
        //向左
        i = 1;//迭代数
        while ((index_x - i) >= 0 && (index_x - i) <= 18
                && index_y >= 0 && index_y <= 18
                && color == qizi[index_x - i][index_y]) {
            count++;
            i++;
        }
        if (count == 5) {
            flag = true;
        }

        //判断纵向棋子是否相连
        count = 1;
        i = 1;//迭代数
        while ((index_x) >= 0 && index_x <= 18
                && (index_y + i) >= 0 && (index_y + i) <= 18
                && color == qizi[index_x][index_y + i]) {
            count++;
            i++;
        }

        i = 1;//迭代数
        while ((index_x) >= 0 && (index_x) <= 18
                && (index_y - i) >= 0 && (index_y - i) <= 18
                && color == qizi[index_x][index_y - i]) {
            count++;
            i++;
        }
        if (count == 5) {
            flag = true;
        }

        //判断斜向棋子是否相连（左上右下）
        count = 1;
        //左上
        i = 1;//迭代数
        while ((index_x - i) >= 0 && (index_x - i) <= 18
                && (index_y - i) >= 0 && (index_y - i) <= 18
                && color == qizi[index_x - i][index_y - i]) {
            count++;
            i++;
        }
        //右下
        i = 1;//迭代数
        while ((index_x + i) >= 0 && (index_x + i) <= 18
                && (index_y + i) >= 0 && (index_y + i) <= 18
                && color == qizi[index_x + i][index_y + i]) {
            count++;
            i++;
        }
        if (count == 5) {
            flag = true;
        }

        //判断斜向棋子是否相连（左下右上）
        count = 1;
        //左下
        i = 1;//迭代数
        while ((index_x + i) >= 0 && (index_x + i) <= 18
                && (index_y - i) >= 0 && (index_y - i) <= 18
                && color == qizi[index_x + i][index_y - i]) {
            count++;
            i++;
        }
        //右上
        i = 1;//迭代数
        while ((index_x - i) >= 0 && (index_x - i) <= 18
                && (index_y + i) >= 0 && (index_y + i) <= 18
                && color == qizi[index_x - i][index_y + i]) {
            count++;
            i++;
        }
        if (count == 5) {
            flag = true;
        }
        return flag;
    }

    @Override
    public void run() {
        //判断是否有时间限制
        if (blacktime > 0 && whitetime > 0 && time > 0) {
            while (true) {
                if (isblack) {
                    blacktime--;
                    if (blacktime == 0) {
                        int res = JOptionPane.showConfirmDialog(null, "黑方超时游戏结束，白方胜利，是否继续？");
                        t.stop();
                        if (res == 0) {
                            t.start();
                            t.resume();
                            for (int i = 0; i < 19; i++) {
                                for (int j = 0; j < 19; j++) {
                                    qizi[i][j] = 0;
                                }
                            }
                            isblack = true;
                            game_title = "黑方落子";
                            blacktime = time;
                            whitetime = time;
                            repaint();
                        } else if (res == 1) {
                            game_start = false;
                            t.suspend();
                        }
                    }
                } else {
                    whitetime--;
                    if (whitetime == 0) {
                        int res = JOptionPane.showConfirmDialog(null, "白方超时游戏结束，黑方胜利，是否继续？");
                        t.stop();
                        t.resume();
                        if (res == 0) {
                            t.start();
                            for (int i = 0; i < 19; i++) {
                                for (int j = 0; j < 19; j++) {
                                    qizi[i][j] = 0;
                                }
                            }
                            isblack = true;
                            game_title = "黑方落子";
                            blacktime = time;
                            whitetime = time;
                            repaint();
                            t.resume();
                        } else if (res == 1) {
                            game_start = false;
                            t.suspend();
                        }
                    }
                }
                blackmessage = blacktime + "";
                whitemessage = whitetime + "";
                repaint();
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
